
require 'lib/mercury/lib/generators/big_input.rb'
require 'lib/mercury/lib/generators/small_input.rb'
require 'lib/mercury/lib/generators/param_input.rb'
require 'lib/mercury/lib/base_configs/bootstrap.rb'
require 'rubygems'
require 'zip/zip'
require 'net/scp'

class Input
 
  def self.write(system, simulation, integration_parameters, temp_bodies)
    bodies = []
    particles = []
    small_inputs = []
    body_type_planet_id = BodyType.find(:first, :conditions => { :name => "planet" }).id
    body_type_test_particle_id = BodyType.find(:first, :conditions => { :name => "test_particle" }).id
    
    temp_bodies.each do |body| #fix magic numbers to planet_type.name = foo
      if body.body_type_id.to_i == body_type_planet_id
        bodies << body
      elsif body.body_type_id.to_i == body_type_test_particle_id
        particles << body
      end
    end
    
    big_input = BigInput.write(integration_parameters, bodies)
    particles = self.modify_particle_array(particles, integration_parameters)
   
    particles.each do |sub_particles|
      small_inputs << SmallInput.create_file_content(integration_parameters, sub_particles)
    end
		param_input = ParamInput.write(integration_parameters, system.mass)
    self.generate_simulations(simulation.id, big_input, small_inputs, param_input)
  end
  
  def self.modify_particle_array(particles, integration_parameters) #Slice small inputs into individual sims
    modified_particles = []
    per_sim = integration_parameters.particles_per_simulation.to_i
    0.step(particles.length, per_sim) do |i|
      if (i+per_sim) > particles.length
        per_sim = particles.length - i       
      end
      modified_particles << particles[i...i+per_sim]
    end
    return modified_particles  
  end
  
  def self.generate_simulations(sim_id, big_input, small_inputs, param_input) #generate configs and start mercury
    scp = Net::SCP.start("waradmiral.physics.weber.edu", "Exoplanet", :password => "b!osphere1")
    ssh = Net::SSH.start("waradmiral.physics.weber.edu", "Exoplanet", :password => "b!osphere1")
    i=1
    small_inputs.each do |small|
      file_input = FileInput.new
      element_input = ElementInput.new
      message_input = MessageInput.new
      start_mercury = StartMercury.new
      write_data_back = WriteDataBack.new(sim_id)
      
      files_to_zip = {
        'configs/big.in' => big_input,
        'configs/small.in' => small,
        'configs/param.in' => param_input,
        'files.in' => file_input.content,
        'message.in' => message_input.content,
        'element.in' => element_input.content,
        'start_mercury.csh' => start_mercury.content,
        'write_data_back.rb'=> write_data_back.content
      }
      
      new_sim = Zip::ZipOutputStream::open("tmp/system_id_#{sim_id}_sim_number_#{i}.zip") do |io|
        files_to_zip.each_pair do |key,value|
          io.put_next_entry(key)
          io.write(value)
        end
      end
      scp.upload! "tmp/system_id_#{sim_id}_sim_number_#{i}.zip", "/Volumes/RAID/Exoplanet/simulation_zips"
      ssh.exec!("/Volumes/RAID/Exoplanet/start_simulation.sh system_id_#{sim_id}_sim_number_#{i}.zip system_id_#{sim_id}_sim_number_#{i}")
      i+=1
    end
  end
end

